package com.after.saas.file.service;

import com.after.saas.file.constants.ModuleEnum;
import com.after.saas.file.function.ExcelConsumer;
import com.after.saas.file.listener.DefaultReadEventListener;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * @Classname EasyExcelService
 * @Description TODO
 * @Date 2021/3/26 17:57
 * @Created by hjchen
 */

@Slf4j
@Service
public class EasyExcelService {

    public List read(String fileName, String moduleCode) {
        ExcelConsumer consumer = getConsumer(moduleCode);
        DefaultReadEventListener defaultReadEventListener = new DefaultReadEventListener(consumer);
        File excelFile = new File(fileName);
        EasyExcel.read(excelFile, getType(moduleCode), defaultReadEventListener).extraRead(CellExtraTypeEnum.COMMENT)
                .extraRead(CellExtraTypeEnum.HYPERLINK)
                .extraRead(CellExtraTypeEnum.MERGE)
                .autoCloseStream(true)
                .sheet().doRead();
        return defaultReadEventListener.getData();
    }

    public List read(InputStream inputStream, String moduleCode) {
        ExcelConsumer consumer = getConsumer(moduleCode);
        DefaultReadEventListener defaultReadEventListener = new DefaultReadEventListener(consumer);
        EasyExcel.read(inputStream, getType(moduleCode), defaultReadEventListener)
                .extraRead(CellExtraTypeEnum.COMMENT)
                .extraRead(CellExtraTypeEnum.HYPERLINK)
                .extraRead(CellExtraTypeEnum.MERGE)
                .autoCloseStream(true)
                .sheet().doRead();
        return defaultReadEventListener.getData();
    }

    public ExcelConsumer getConsumer(String moduleCode) {
        ModuleEnum moduleEnum = ModuleEnum.getClazzByCode(moduleCode);
        try {
            assert moduleEnum != null;
            return (ExcelConsumer) moduleEnum.getClazz().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Class getType(String moduleCode) {
        ModuleEnum moduleEnum = ModuleEnum.getClazzByCode(moduleCode);
        assert moduleEnum != null;
        Type[] types = moduleEnum.getClazz().getGenericInterfaces();
        ParameterizedType parameterizedType = (ParameterizedType) types[0];
        Type type = parameterizedType.getActualTypeArguments()[0];
        try {
            return Class.forName(type.getTypeName());
        } catch (Exception e) {
        }
        return null;
    }
}